# -*- coding: utf-8 -*-
"""
@Time ： 2023/9/22 0022 14:30
@Auth ： ysc
@File ：base_page.py
@IDE ：PyCharm
"""
import time, random, string
from selenium.webdriver.support.wait import WebDriverWait as WD
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import (
    TimeoutException,
    NoAlertPresentException,
)
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from Config.config import LOCATE_MODE
from Lib.log import log


class BasePage(object):
    """结合显示等待封装一些selenium内置方法"""

    def __init__(self, driver, timeout=20):
        self.driver = driver
        self.timeout = timeout
        self.wait = WD(self.driver, self.timeout)
        self.action = ActionChains(driver)

    @staticmethod
    def element_locator(func, locator):
        """
        元素定位器
        """
        name, value = locator
        return func(LOCATE_MODE[name], value)

    def find_element(self, locator):
        """
        获取单个元素
        """
        try:
            ele = BasePage.element_locator(lambda *args: self.wait.until(
                EC.presence_of_element_located(args)), locator)
            return ele
        except TimeoutException as e:
            log.error('found "{}" timeout!'.format(locator), e)

    def find_elements(self, locator):
        """
        获取多个元素
        """
        try:
            elements = BasePage.element_locator(lambda *args: self.wait.until(
                EC.presence_of_all_elements_located(args)), locator)
            return elements
        except Exception as e:
            log.error('found "{}" timeout!'.format(locator), e)

    def is_element_exist(self, locator):
        """
        判断元素是否可见
        """
        try:
            BasePage.element_locator(lambda *args: self.wait.until(
                EC.visibility_of_element_located(args)), locator)
        except TimeoutException:
            log.info('Error: element "{}" not exist'.format(locator))
            return False
        return True

    def is_click(self, locator):
        """
        判断元素是否可见并且是enable的
        """
        try:
            ele = BasePage.element_locator(lambda *args: self.wait.until(
                EC.element_to_be_clickable(args)), locator)
            return ele
        except TimeoutException as e:
            log.error("元素不可以点击", e)

    def is_alert(self):
        """
        判断页面是否存在alert
        """
        try:
            re = WD(self.driver, self.timeout).until(EC.alert_is_present())
        except (TimeoutException, NoAlertPresentException) as e:
            log.error("no found alert", e)
        else:
            return re

    def switch_to_frame(self, locator):
        """
        判断frame是否存在，存在就跳到frame
        """
        log.info('switching to iframe "{}"'.format(locator))
        try:
            BasePage.element_locator(lambda *args: self.wait.until(
                EC.frame_to_be_available_and_switch_to_it(args)), locator)
        except TimeoutException as e:
            log.error('found "{}" timeout！切换frame失败'.format(locator), e)

    def switch_to_default_frame(self):
        """
        返回默认的frame
        """
        log.info('switch back to default iframe')
        try:
            self.driver.switch_to.default_content()
        except Exception as e:
            log.error(e)

    def get_alert_text(self):
        """
        获取alert的提示信息
        """
        alert = self.is_alert()
        if alert:
            return alert.text
        else:
            return None

    def get_element_text(self, locator, name=None):
        """
        获取input输入框的输入内容、元素的属性值或者text信息
        """
        try:
            element = self.find_element(locator)
            if name:
                return element.get_attribute(name)
            else:
                return element.text
        except AttributeError:
            log.error('get "{}" text failed return None'.format(locator))

    def load_url(self, url):
        """
        加载url
        """
        log.info('string upload url "{}"'.format(url))
        self.driver.maximize_window()
        self.driver.get(url)
        self.driver.implicitly_wait(10)

    def get_source(self):
        """
        获取页面源码
        """
        return self.driver.page_source

    def send_keys(self, locator, value=''):
        """
        写数据
        """
        log.info('input "{}"'.format(value))
        try:
            element = self.find_element(locator)
            #element.clear()
            element.send_keys(value)
        except AttributeError as e:
            log.error(e)

    def clear_and_send_keys(self, locator, value=''):
        """
        写数据
        """
        log.info('input "{}"'.format(value))
        try:
            element = self.find_element(locator)
            element.clear()
            element.send_keys(value)
        except AttributeError as e:
            log.error(e)

    def clear(self, locator):
        """
        清理input输入框内容
        """
        log.info('clearing data')
        try:
            element = self.find_element(locator)
            element.clear()
        except AttributeError as e:
            log.error(e)

    def click(self, locator):
        """
        点击某个元素
        """
        log.info('click "{}"'.format(locator))
        element = self.is_click(locator)
        if element:
            element.click()
        else:
            log.info('the "{}" unclickable!'.format(locator))

    def mouse_move(self, locator):
        """
        鼠标悬停
        """
        log.info('mouse_move "{}"'.format(locator))
        try:
            element = self.find_element(locator)
            self.action.move_to_element(element).perform()
        except Exception as e:
            log.error(e)

    def context_click(self, locator):
        """
        鼠标右击
        """
        log.info('context_click "{}"'.format(locator))
        try:
            element = self.find_element(locator)
            self.action.context_click(element).perform()
        except Exception as e:
            print(e)

    def double_click(self, locator):
        """
        鼠标双击
        """
        log.info('double_click "{}"'.format(locator))
        try:
            element = self.find_element(locator)
            self.action.double_click(element).perform()
        except Exception as e:
            log.error(e)

    def drag_drop(self, locator1, locator2):
        """
        鼠标拖拽
        """
        log.info('drag_drop "{}_and_{}"'.format(locator1, locator2))
        try:
            element1 = self.find_element(locator1)
            element2 = self.find_element(locator2)
            self.action.drag_and_drop(element1, element2).perform()
        except Exception as e:
            log.error(e)

    def enter_key(self, locator):
        """
        enter 回车键
        """
        log.info('keydown enter')
        self.send_keys(locator, Keys.ENTER)

    @staticmethod
    def sleep(num=0):
        """
        强制等待
        """
        log.info('sleep "{}" minutes'.format(num))
        time.sleep(num)

    @staticmethod
    def generate_random_string(length):
        letters = string.ascii_letters
        return ''.join(random.choice(letters) for _ in range(length))


if __name__ == "__main__":
    pass
